Let’s see how different neighborhood matrix styles can impact the estimates of spatial regression models. Again, run the code below in order to have the data in place for this exercises.
## Reading layer `OGRGeoJSON' from data source
## `https://geoportal.stadt-koeln.de/arcgis/rest/services/Basiskarten/kgg/MapServer/20/query?where=objectid+is+not+null&text=&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&distance=&units=esriSRUnit_Foot&relationParam=&outFields=*&returnGeometry=true&returnTrueCurves=false&maxAllowableOffset=&geometryPrecision=&outSR=4326&havingClause=&returnIdsOnly=false&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&gdbVersion=&historicMoment=&returnDistinctValues=false&resultOffset=&resultRecordCount=&returnExtentOnly=false&datumTransformation=¶meterValues=&rangeValues=&quantizationParameters=&featureEncoding=esriDefault&f=geojson'
## using driver `GeoJSON'
## Simple feature collection with 543 features and 20 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 6.77253 ymin: 50.83045 xmax: 7.162028 ymax: 51.08496
## Geodetic CRS: WGS 84
## ℹ Using "','" as decimal and "'.'" as grouping mark. Use `read_delim()` for more control.
## Rows: 949 Columns: 79
## ── Column specification ──────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (3): wahl, ags, gebiet-name
## dbl (71): gebiet-nr, max-schnellmeldungen, anz-schnellmeldungen, A1, A2, A3, A, B, B1, C, D, E, F, D1, F1, D2,...
## lgl (4): D30, F30, D31, F31
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
voting_districts <-
glue::glue(
"https://geoportal.stadt-koeln.de/arcgis/rest/services/Basiskarten/kgg/\\
MapServer/20/query?where=objectid+is+not+null&text=&objectIds=&time=&\\
geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=\\
esriSpatialRelIntersects&distance=&units=esriSRUnit_Foot&relationParam=&\\
outFields=*&returnGeometry=true&returnTrueCurves=false&maxAllowableOffset=\\
&geometryPrecision=&outSR=4326&havingClause=&returnIdsOnly=false&return\\
CountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=\\
&returnZ=false&returnM=false&gdbVersion=&historicMoment=&returnDistinct\\
Values=false&resultOffset=&resultRecordCount=&returnExtentOnly=false&datum\\
Transformation=¶meterValues=&rangeValues=&quantizationParameters=&\\
featureEncoding=esriDefault&f=geojson"
) %>%
sf::st_read(as_tibble = TRUE) %>%
sf::st_transform(3035) %>%
dplyr::transmute(Stimmbezirk = as.numeric(nummer))
afd_votes <-
glue::glue(
"https://www.stadt-koeln.de/wahlen/bundestagswahl/09-2021/praesentation/\\
Open-Data-Bundestagswahl476.csv"
) %>%
readr::read_csv2() %>%
dplyr::transmute(Stimmbezirk = `gebiet-nr`, afd_share = (F1 / F) * 100)
election_results <-
dplyr::left_join(
voting_districts,
afd_votes,
by = "Stimmbezirk"
)
immigrants_cologne <-
z11::z11_get_100m_attribute(STAATSANGE_KURZ_2) %>%
terra::crop(election_results) %>%
terra::mask(terra::vect(election_results))
inhabitants_cologne <-
z11::z11_get_100m_attribute(Einwohner) %>%
terra::crop(election_results) %>%
terra::mask(terra::vect(election_results))
immigrant_share_cologne <-
(immigrants_cologne / inhabitants_cologne) * 100
election_results <-
election_results %>%
dplyr::mutate(
immigrant_share =
exactextractr::exact_extract(immigrant_share_cologne, ., 'mean', progress = FALSE),
inhabitants =
exactextractr::exact_extract(inhabitants_cologne, ., 'mean', progress = FALSE)
)
style = "minmax" in the spdep:nb2listw() function.